﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConcreteService
{
    public class MemoryCache : ICache
    {
        private static IDictionary<Type, MemoryCache> dicManager = new Dictionary<Type, MemoryCache>();
        private IDictionary<string, object> dicObject;

        private MemoryCache()
        {
            this.dicObject = new Dictionary<string, object>();
        }

        private static MemoryCache GetInstance<T>()
        {
            Type cacheType = typeof(T);

            if (!dicManager.ContainsKey(cacheType))
            {
                dicManager.Add(cacheType, new MemoryCache());

                if (dicManager.ContainsKey(cacheType))
                    dicManager[cacheType] = dicManager[cacheType];
                else
                    dicManager.Add(cacheType, dicManager[cacheType]);
            }

            return dicManager[cacheType];
        }

        public void Put<T>(string key, T val)
        {
            var manager = GetInstance<T>();

            if (manager.dicObject.ContainsKey(key))
                manager.dicObject[key] = val;
            else
                manager.dicObject.Add(key, val);
        }

        public T Get<T>(string key)
        {
            T objRet = default(T);

            var manager = GetInstance<T>();
            if (manager.dicObject.ContainsKey(key))
                objRet = (T)manager.dicObject[key];

            return objRet;
        }

        public List<T> List<T>()
        {
            var manager = GetInstance<T>();
            List<T> lst = new List<T>();
            foreach (var item in manager.dicObject.Values)
            {
                lst.Add((T)item);
            }
            return lst;
        }

        public void Delete<T>(string key)
        {
            var manager = GetInstance<T>();
            if (manager.dicObject.ContainsKey(key))
                manager.dicObject.Remove(key);
        }

        public void Clear<T>()
        {
            var manager = GetInstance<T>();
            manager.dicObject.Clear();
        }
    }
}
